// 弹窗复选
import React from 'react';
import { Modal, Checkbox, Tree, Input, message } from 'antd';
import TRNotification from '#/utils/notification';
import { CloseOutlined, SearchOutlined } from '#/utils/antdIcons';
import styles from './index.less';

/**
 * title: 顶部名称
 * value: 选中值
 * treeData: 树形结构
 */
class MyModalComponent extends React.Component {
  constructor(props) {
    super(props);
    this.title = props?.title || '结算单元';
    this.treeData = props?.treeData || [];
    this.nodeMap = props?.nodeMap || {};
    this.state = {
      visible: true,
      checkAll: false,
      indeterminate: false,
      autoExpandParent: true,
      checkedKeys: [],
      checkedNodes: [],
      expandedKeys: [],
      searchValue: '',
    };
    this.deepLv = 1; // 最深叶子等级
    this.treeDataMap = this._tree2map(this.treeData, [], null, 1);
    this.leafNodes = this.treeDataMap.filter((x) => x.lv === this.deepLv);

    this._onSearch = this._onSearch.bind(this); // 搜索
    this._onChangeAll = this._onChangeAll.bind(this); // 全选
    this._onClearAll = this._onClearAll.bind(this); // 清空
    this._onCheckTree = this._onCheckTree.bind(this); // 树选择
    this._onExpandTree = this._onExpandTree.bind(this); // 树展开
    this._onCancel = this._onCancel.bind(this); // 取消
    this._onOk = this._onOk.bind(this); // 提交
  }

  componentDidMount() {
    this._onCheckTree(this.props.value);
  }

  _tree2map = (tree = [], list = [], parentKey = null, lv = 1) => {
    // 降维,key要唯一
    if (lv > this.deepLv) this.deepLv = lv;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      node.key = node.value;
      node.title = node.label;
      node.lv = lv;
      node.parentKey = parentKey;
      list.push({
        key: node.value,
        title: node.label,
        parentKey,
        lv,
      });
      if (node.children?.length) {
        this._tree2map(node.children, list, node.key, lv + 1);
      }
    }
    return list;
  };

  _isChinese = (s) => {
    // 中文全匹配
    var ret = true;
    for (var i = 0; i < s.length; i++) ret = ret && s.charCodeAt(i) >= 10000;
    return ret;
  };

  _onSearch = (e) => {
    let expandedKeys = [];
    const { value } = e.target;
    if (value && this._isChinese(value)) {
      expandedKeys = this.treeDataMap
        .map((x) => (x.title.indexOf(value) > -1 ? x.parentKey : null))
        .filter((item, i, self) => item && self.indexOf(item) === i);
    }
    this.setState({
      expandedKeys,
      searchValue: value,
      autoExpandParent: true,
    });
  };

  _onChangeAll = (e) => {
    const checkAll = e.target.checked,
      checkedNodes = checkAll ? [...this.leafNodes] : [],
      checkedKeys = checkedNodes.map((x) => x.key);
    this.setState({
      checkAll,
      checkedKeys,
      checkedNodes,
      indeterminate: false,
    });
  };

  _onClearAll = () => {
    this.setState({
      checkAll: false,
      indeterminate: false,
      checkedKeys: [],
      checkedNodes: [],
      expandedKeys: [],
    });
  };

  _onCheckTree = (val) => {
    const checkedNodes = this.leafNodes.filter((x) => val.includes(x.key)),
      checkedKeys = checkedNodes.map((x) => x.key),
      checkAll = !!checkedKeys.length && checkedKeys.length === this.leafNodes.length,
      indeterminate = !!checkedKeys.length && checkedKeys.length < this.leafNodes.length;

    this.setState({
      checkedKeys,
      checkedNodes,
      checkAll,
      indeterminate,
    });
  };

  _onExpandTree = (expandedKeys) => {
    this.setState({
      expandedKeys,
      autoExpandParent: false,
    });
  };

  _onRemove = (idx) => {
    let { checkedKeys, checkedNodes, indeterminate, checkAll } = this.state;
    checkedNodes.splice(idx, 1);
    checkedKeys = checkedNodes.map((x) => x.key);
    if (!checkedKeys.length) {
      indeterminate = false;
      checkAll = false;
    }
    this.setState({
      checkAll,
      checkedKeys,
      checkedNodes,
      indeterminate,
    });
  };

  _onCancel = () => {
    this.setState({
      visible: false,
    });
    this.props.onPress({ index: 0 });
  };

  _onOk = () => {
    const { checkedKeys, checkedNodes } = this.state;
    if (!checkedKeys.length) {
      message.warning('请至少选择一项');
      return;
    }
    const len = checkedKeys.length;
    const allLen = this.leafNodes.length;
    const selected = len === allLen ? '全部交易单元' : `${len}项/${allLen}项`;
    this.setState({
      visible: false,
    });
    this.props.onPress({
      index: 1,
      checkedKeys,
      checkedNodes,
      selected,
    });
  };
  orderSort(obj1, obj2) {
    var a = obj1.title;
    var b = obj2.title;
    if (b > a) {
      return -1;
    } else if (b < a) {
      return 1;
    } else {
      return 0;
    }
  }
  render() {
    const {
      visible,
      checkAll,
      indeterminate,
      autoExpandParent,
      checkedKeys = [],
      checkedNodes = [],
      expandedKeys = [],
      searchValue = '',
    } = this.state;

    const loop = (data = []) =>
      data.map((item) => {
        const { lv, parentKey, key } = item;
        const index = item.title.indexOf(searchValue);
        const beforeStr = item.title.substr(0, index);
        const afterStr = item.title.substr(index + searchValue.length);
        const _title =
          index > -1 ? (
            <span>
              {beforeStr}
              <span className={styles.search_act}>{searchValue}</span>
              {afterStr}
              {this.nodeMap[item.title] && (
                <span style={{ color: '#7A7D7F', marginLeft: 4 }}>{`(${
                  this.nodeMap[item.title] || ''
                })`}</span>
              )}
            </span>
          ) : (
            <span>
              {item.title}
              {this.nodeMap[item.title] && (
                <span style={{ color: '#7A7D7F', marginLeft: 4 }}>{`(${
                  this.nodeMap[item.title] || ''
                })`}</span>
              )}
            </span>
          );
        if (item.children) {
          return { key, title: _title, lv, parentKey, children: loop(item.children) };
        }

        return { key, title: _title, lv, parentKey };
      });

    return (
      <Modal
        width={560}
        className={styles.modal}
        visible={visible}
        centered={true}
        maskClosable={true}
        title={
          <div key="title" className={styles.modal_title}>
            {this.title}
          </div>
        }
        cancelText={'取消'}
        onCancel={this._onCancel}
        okText={'提交'}
        onOk={this._onOk}
      >
        <div className={styles.modal_body}>
          <div className={styles.treebox}>
            <div className={styles.box_header}>
              <Input
                placeholder="搜索"
                suffix={<SearchOutlined />}
                allowClear={true}
                onChange={this._onSearch}
              />
            </div>
            <div className={styles.box_content}>
              <Checkbox
                checked={checkAll}
                indeterminate={indeterminate}
                onChange={this._onChangeAll}
              >
                全选
              </Checkbox>
              <Tree
                treeData={loop(this.treeData)}
                blockNode={true}
                checkable={true}
                checkedKeys={checkedKeys}
                expandedKeys={expandedKeys}
                autoExpandParent={autoExpandParent}
                onExpand={this._onExpandTree}
                onCheck={this._onCheckTree}
              />
            </div>
          </div>

          <div className={styles.choosebox}>
            <div className={styles.box_header}>
              <div>{`已选${checkedNodes.length}项`}</div>
              <div className={styles.clear} onClick={this._onClearAll}>
                清空
              </div>
            </div>
            <div className={styles.box_content}>
              <ul className={styles.chooseList}>
                {checkedNodes.sort(this.orderSort).map((item, idx) => {
                  return (
                    <li key={item.key}>
                      <div className={styles.chooseName}>
                        {item.title}
                        {this.nodeMap[item.title] && (
                          <span style={{ color: '#7A7D7F', marginLeft: 4 }}>{`(${
                            this.nodeMap[item.title] || ''
                          })`}</span>
                        )}
                      </div>
                      <CloseOutlined
                        className={styles.close}
                        onClick={this._onRemove.bind(this, idx)}
                      />
                    </li>
                  );
                })}
              </ul>
            </div>
          </div>
        </div>
      </Modal>
    );
  }
}

class MyModal {
  __key__ = '';

  show = (props) => {
    return new Promise((resolve) => {
      if (this.__key__ !== '') return;
      this.__key__ = String(Date.now());
      TRNotification.add({
        key: this.__key__,
        content: (
          <MyModalComponent
            {...props}
            onPress={(result) => {
              TRNotification.remove(this.__key__);
              this.__key__ = '';
              resolve(result);
            }}
          />
        ),
        duration: null,
      });
    });
  };

  dismiss = () => {
    if (this.__key__.length > 0) {
      TRNotification.remove(this.__key__);
      this.__key__ = '';
    }
  };
}

export default new MyModal();
